+
+ The fact that
+ faster is slower
+ is counter-intuitive but it is a fact. The more we push the more we are
+ slowing down the system.
+
When money and pressure are in the game, fear, uncertainty, and doubt
spread out rapidly. So we rush, as fast as we can, and when a team has
nothing to do, it becomes a disaster: money are being burned.
- Teams will overproduce. They will do every pieces they can as they are
- autonomous: product team will pitch their features, designers will design
- every pages, developers will rush to code forgetting why the customer
- needs this precise feature. They will then struggle to get these pieces to
- the very end when they will transfer them to the others teams. So the fear
- of having nothing to give to the next team pushes us to produce just in
- case. Bugs lead to more bugs that lead to more bugs. Multitasking will
- drastically drop the productivity.
+ Teams will overproduce. They will do every pieces they can as they can:
+ product team will prepare their features, designers will design every
+ screens, developers will rush to code. Then, they struggle to get these
+ pieces to the very end. So the fear of having nothing to give to the next
+ team pushes us to produce just in case. Bugs lead to more bugs that lead
+ to more bugs. The productivity drops.
- But the best way to succeed is to ask: "Is this what you need? How can I
- help you?".
+ So the pull system is here to change our priority.
+ Developpers are the clients of the Designer team, as well as Designers are
+ the client of the Product team. Focusing on the lead time is asking to the
+ next team: "Is this what you need? How can we help each other?". This is
+ the question of team work.
+
diff --git a/src/modules/pull-system/article/FlowHypothesis.vue b/src/modules/pull-system/article/FlowHypothesis.vue
index cb1ee05..ff930fc 100644
--- a/src/modules/pull-system/article/FlowHypothesis.vue
+++ b/src/modules/pull-system/article/FlowHypothesis.vue
@@ -2,7 +2,18 @@
-
Here our hypothesis:
+ We need some hypothesis to start with. Here are ours:
+
+ -
+ The more feature done in parallel, the more it is difficult to focus and
+ it is more likely to introduce a defect.
+
+ -
+ it takes the same amount of time for each team to complete a task
+ same task time
+
+
+
diff --git a/src/modules/pull-system/article/FlowSingleSimulation.vue b/src/modules/pull-system/article/FlowSingleSimulation.vue
index 7e437ac..9ab1bd5 100644
--- a/src/modules/pull-system/article/FlowSingleSimulation.vue
+++ b/src/modules/pull-system/article/FlowSingleSimulation.vue
@@ -1,3 +1,8 @@
+
+
- Pull system wins! The fact that
- faster is slower
-
- is counter-intuitive but it is a fact. The more we push the more we are
- slowing down the system.
+ Not so obvious... So what can we learn? What are the patterns we can
+ identify?
+
+
+ In a primarly push system, we see teams struggling and
+ stuck reworking the same features again and again to finally having all
+ features live all at once.
+
+
+ In a primarly pull system however, we see a smoother
+ flow of work with teams able to pass on features more easily and
+ continuously, leading to a more steady and predictable delivery. It's not
+ perfect, but you may have see a balai of features when teams work and
+ finish at the same time. 💃🏽
+
Before any conclusion, comparing two simulations is not enough. Let's be
- more scientific here and let's generate 200 projects delivering 200
- features each and see what happens.
+ more scientific here and let's generate 200 projects delivering the 20
+ features of the Newsletter app and see what happens.
diff --git a/src/modules/pull-system/feature/FlowDashboard.vue b/src/modules/pull-system/feature/FlowDashboard.vue
index 6bb0829..3e461d8 100644
--- a/src/modules/pull-system/feature/FlowDashboard.vue
+++ b/src/modules/pull-system/feature/FlowDashboard.vue
@@ -10,6 +10,20 @@ const featureStore = useFeatureStore()
+
+ Days
+
+ {{ featureStore.meta.totalDays }}d
+
+
+
+ ETA
+
+ {{ featureStore.eta }}
+ days
+
+
Features
@@ -24,10 +38,6 @@ const featureStore = useFeatureStore()
{{ featureStore.meta.teamWorkExperience.toFixed(2) }}
-->
-
- Mean complexity
-
{{ featureStore.meanComplexity }}
-
Mean lead time
@@ -43,18 +53,12 @@ const featureStore = useFeatureStore()
- Days
-
- {{ featureStore.meta.totalDays }}d
-
+ Quality issues
+
{{ featureStore.qualityIssues }}
- ETA
-
- {{ featureStore.eta }}
- days
-
+ Mean complexity
+
{{ featureStore.meanComplexity }}
diff --git a/src/modules/pull-system/feature/feature-board.ts b/src/modules/pull-system/feature/feature-board.ts
index aff2b98..66c9767 100644
--- a/src/modules/pull-system/feature/feature-board.ts
+++ b/src/modules/pull-system/feature/feature-board.ts
@@ -23,11 +23,11 @@ const HARD_STOP = 5000
const getQualityIssue = ({
complexity,
- tasksInParallel,
+ featuresInParallel,
teamWorkExperience
}: {
complexity: number
- tasksInParallel: number
+ featuresInParallel: number
teamWorkExperience: number
}): boolean => {
const qualityProbability = getQualityProbability(
@@ -35,7 +35,7 @@ const getQualityIssue = ({
teamWorkExperience
)
- const multiplicator = getOverburdenMultiplicator(tasksInParallel)
+ const multiplicator = getOverburdenMultiplicator(featuresInParallel)
const quality = randomFloat(0, 1)
return quality > qualityProbability / multiplicator
@@ -91,7 +91,7 @@ export const initBoard = (
initialFeatures.forEach((feature) => {
const step = pickRandomElement(steps)
feature.status = pickRandomElement(['doing', 'done'])
- feature.step = Math.max(step.stepIndex, 1)
+ feature.step = step.stepIndex
feature.qualityIssue = 0
})
@@ -141,7 +141,7 @@ export const getFeaturesForNextDay = ({
const hasQualityIssue = getQualityIssue({
complexity: feature.complexity,
- tasksInParallel: features.filter(
+ featuresInParallel: features.filter(
(f) => f.status === 'doing' && f.step === feature.step
).length,
teamWorkExperience
diff --git a/src/modules/pull-system/feature/feature-store.ts b/src/modules/pull-system/feature/feature-store.ts
index 523acbe..d85e82f 100644
--- a/src/modules/pull-system/feature/feature-store.ts
+++ b/src/modules/pull-system/feature/feature-store.ts
@@ -37,7 +37,10 @@ export const useFeatureStore = defineStore('feature', {
async initBoard(type: 'bird' | 'mobile-app', limit?: number) {
this.backlog = newBacklog(type, limit)
this.steps = featureSteps
- this.features = initBoard(this.steps, this.backlog)
+ const initialSteps = featureSteps.filter(
+ (step) => step.title !== 'Release' && step.title !== 'Development'
+ )
+ this.features = initBoard(initialSteps, this.backlog)
this.backlog = this.backlog.filter(
(l) => !this.features.find((f) => f.name === l.name)
@@ -56,6 +59,8 @@ export const useFeatureStore = defineStore('feature', {
isProjectFinished: (state) => isProjectFinished(state.features),
meanComplexity: (state) => getMeanComplexity(state.features),
meanLeadTime: (state) => getMeanLeadTime(state.features),
+ qualityIssues: (state) =>
+ state.features.map((f) => f.qualityIssue).reduce((a, b) => a + b, 0),
meanQualityIssue: (state) => getMeanQualityIssue(state.features),
taktTime: (state): string => {
const taktTime = (
diff --git a/src/modules/pull-system/simulation/simulation-store.ts b/src/modules/pull-system/simulation/simulation-store.ts
index a9f6775..b0b9412 100644
--- a/src/modules/pull-system/simulation/simulation-store.ts
+++ b/src/modules/pull-system/simulation/simulation-store.ts
@@ -66,7 +66,7 @@ export const useSimulationStore = defineStore('dashboard', {
actions: {
async simulate(strategy: Strategy) {
const steps = featureSteps
- const backlog = await instance.newBacklog('bird')
+ const backlog = await instance.newBacklog('mobile-app')
const features = await instance.initBoard(steps, backlog)
const newState = await instance.simulate(