Reuse the declaration validation path across siblings
This commit is contained in:
26
command.go
26
command.go
@@ -443,30 +443,31 @@ func validateCommandDeclaration(command Command) error {
|
|||||||
|
|
||||||
func validateCommandPlacement(command Command) error {
|
func validateCommandPlacement(command Command) error {
|
||||||
var issues []error
|
var issues []error
|
||||||
collectDeclarationIssues(command, nil, true, &issues)
|
// Keep the grown slice header across recursive calls so siblings reuse capacity.
|
||||||
return errors.Join(issues...)
|
var path []string
|
||||||
}
|
var collectDeclarationIssues func(Command, bool)
|
||||||
|
collectDeclarationIssues = func(command Command, root bool) {
|
||||||
func collectDeclarationIssues(command Command, parents []string, root bool, issues *[]error) {
|
|
||||||
if command.record == nil {
|
if command.record == nil {
|
||||||
*issues = append(*issues, errors.New("invalid zero command declaration"))
|
issues = append(issues, errors.New("invalid zero command declaration"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
record := command.record
|
record := command.record
|
||||||
path := append(parents, record.name)
|
length := len(path)
|
||||||
|
path = append(path, record.name)
|
||||||
|
defer func() { path = path[:length] }()
|
||||||
var label string
|
var label string
|
||||||
if len(record.issues) > 0 || (record.rootOnly && !root) {
|
if len(record.issues) > 0 || (record.rootOnly && !root) {
|
||||||
label = commandpath.Path(path).String()
|
label = commandpath.Path(path).String()
|
||||||
}
|
}
|
||||||
for _, issue := range record.issues {
|
for _, issue := range record.issues {
|
||||||
if label != "" {
|
if label != "" {
|
||||||
*issues = append(*issues, fmt.Errorf("command %q: %w", label, issue))
|
issues = append(issues, fmt.Errorf("command %q: %w", label, issue))
|
||||||
} else {
|
} else {
|
||||||
*issues = append(*issues, issue)
|
issues = append(issues, issue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if record.rootOnly && !root {
|
if record.rootOnly && !root {
|
||||||
*issues = append(*issues, fmt.Errorf("root-only command %q is nested beneath another command", label))
|
issues = append(issues, fmt.Errorf("root-only command %q is nested beneath another command", label))
|
||||||
}
|
}
|
||||||
if record.invalid || record.absent {
|
if record.invalid || record.absent {
|
||||||
return
|
return
|
||||||
@@ -475,9 +476,12 @@ func collectDeclarationIssues(command Command, parents []string, root bool, issu
|
|||||||
if child.record == nil {
|
if child.record == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
collectDeclarationIssues(child, path, false, issues)
|
collectDeclarationIssues(child, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
collectDeclarationIssues(command, true)
|
||||||
|
return errors.Join(issues...)
|
||||||
|
}
|
||||||
|
|
||||||
func validateCommandName(name string) error {
|
func validateCommandName(name string) error {
|
||||||
return commandpath.ValidateComponent(name)
|
return commandpath.ValidateComponent(name)
|
||||||
|
|||||||
@@ -491,8 +491,11 @@ Also discussed in the [responsibility assessment](A1-responsibility.md#machinery
|
|||||||
|
|
||||||
## F22 — P3: Successful declaration validation eagerly formats every full path
|
## F22 — P3: Successful declaration validation eagerly formats every full path
|
||||||
|
|
||||||
**Complete.** The walk reuses a scratch path and formats it only for retained
|
**Complete.** The walk retains one shared scratch slice header across siblings,
|
||||||
issues or root-only placement errors. Focused declaration and registry tests pass.
|
truncates on every return, and formats only retained issues or root-only placement
|
||||||
|
errors. The [R1 follow-up](../remediation.md#r1--p3-declaration-validation-can-still-copy-a-shared-deep-prefix-for-every-sibling)
|
||||||
|
completes the initial path refactor and records source review, passing focused
|
||||||
|
and full suites, and a deep branching consumer check.
|
||||||
|
|
||||||
`collectDeclarationIssues` copies and formats each ancestral path before knowing
|
`collectDeclarationIssues` copies and formats each ancestral path before knowing
|
||||||
whether a diagnostic is needed. A valid depth-N declaration chain incurs Θ(N²)
|
whether a diagnostic is needed. A valid depth-N declaration chain incurs Θ(N²)
|
||||||
|
|||||||
@@ -564,10 +564,11 @@ Neither finding closes merely because the new tree methods exist.
|
|||||||
|
|
||||||
## Stage 17 — Format declaration paths only for diagnostics
|
## Stage 17 — Format declaration paths only for diagnostics
|
||||||
|
|
||||||
**Complete.** Declaration traversal uses the recursive scratch path and formats
|
**Complete.** Declaration traversal now captures one shared scratch slice header,
|
||||||
labels only for emitted issues. Focused declaration, registry and retained-error
|
retaining grown capacity across siblings and truncating on every return. Labels
|
||||||
tests pass offline with Go 1.27.0 and `-mod=readonly`; source review confirms
|
are formatted only for emitted issues. The [R1 follow-up](remediation.md#r1--p3-declaration-validation-can-still-copy-a-shared-deep-prefix-for-every-sibling)
|
||||||
valid paths are not eagerly copied and formatted during this walk.
|
corrects the initial by-value traversal and records source-level complexity
|
||||||
|
verification, passing focused and full suites, and a deep branching consumer check.
|
||||||
|
|
||||||
Findings: F22. Source: `command.go` collectDeclarationIssues.
|
Findings: F22. Source: `command.go` collectDeclarationIssues.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Implementation efficiency remediation
|
# Implementation efficiency remediation
|
||||||
|
|
||||||
Status: one open P3 efficiency finding. Reviewed source:
|
Status: R1 complete; no open findings. Audited source before remediation:
|
||||||
`1cba65fffe966cb70f48c324baf551502544cbad`.
|
`1cba65fffe966cb70f48c324baf551502544cbad`.
|
||||||
|
|
||||||
## Scope and architecture
|
## Scope and architecture
|
||||||
@@ -42,7 +42,7 @@ path, rather than proposing a different algorithm or public contract.
|
|||||||
| 14 | Shared token consumption advances through short spellings and consumed values; it does not rescan each complete short cluster. |
|
| 14 | Shared token consumption advances through short spellings and consumed values; it does not rescan each complete short cluster. |
|
||||||
| 15 | Implementation retains the selected context-local memoization and source ordering. No residual independent suffix walks were found. |
|
| 15 | Implementation retains the selected context-local memoization and source ordering. No residual independent suffix walks were found. |
|
||||||
| 16 | Implementation uses the selected resolver tree and owned-path results for distinct-prefix discovery and descendant lookup. Those selected algorithms were not reopened. |
|
| 16 | Implementation uses the selected resolver tree and owned-path results for distinct-prefix discovery and descendant lookup. Those selected algorithms were not reopened. |
|
||||||
| 17 | **R1:** a child's grown path slice is not retained for siblings, allowing repeated deep-prefix copying. |
|
| 17 | **R1 complete:** the traversal now retains grown scratch-path capacity across siblings. |
|
||||||
| 18 | Operation-preparation extraction preserves the selected independent inputs and existing preflight rules; no new repeated algorithm was introduced. |
|
| 18 | Operation-preparation extraction preserves the selected independent inputs and existing preflight rules; no new repeated algorithm was introduced. |
|
||||||
| 19 | Capture extraction preserves existing selector/scope processing. The explicitly deferred indexing work remains outside this audit. |
|
| 19 | Capture extraction preserves existing selector/scope processing. The explicitly deferred indexing work remains outside this audit. |
|
||||||
| 20 | Operand/error attribution extraction preserves the selected dense reconstruction and replay merge, without introducing general sorting. |
|
| 20 | Operand/error attribution extraction preserves the selected dense reconstruction and replay merge, without introducing general sorting. |
|
||||||
@@ -52,7 +52,18 @@ path, rather than proposing a different algorithm or public contract.
|
|||||||
|
|
||||||
## R1 — P3: Declaration validation can still copy a shared deep prefix for every sibling
|
## R1 — P3: Declaration validation can still copy a shared deep prefix for every sibling
|
||||||
|
|
||||||
**Code:** [command.go](../../command.go), collectDeclarationIssues lines
|
**Complete.** validateCommandPlacement now owns one path slice captured by its
|
||||||
|
recursive collectDeclarationIssues visitor. Each node appends its name and
|
||||||
|
defers truncation to its entry length, including on invalid/absent early returns.
|
||||||
|
Truncation preserves the grown slice header and capacity for subsequent siblings.
|
||||||
|
Successful traversal therefore takes O(N) amortized path work with O(D) scratch
|
||||||
|
storage; diagnostic labels are still formatted only when emitted. Child/issue
|
||||||
|
order, error wrapping, root-only checks and declaration handling are preserved.
|
||||||
|
See [remediation verification](#remediation-verification) for the checks performed.
|
||||||
|
|
||||||
|
The analysis below records the defect at the audited revision.
|
||||||
|
|
||||||
|
**Audited code:** [command.go](../../command.go), collectDeclarationIssues lines
|
||||||
450–479, particularly append at line 456 and recursive calls at line 478.
|
450–479, particularly append at line 456 and recursive calls at line 478.
|
||||||
validateCommandPlacement starts the walk with nil parents; installation reaches
|
validateCommandPlacement starts the walk with nil parents; installation reaches
|
||||||
it through the candidate validator.
|
it through the candidate validator.
|
||||||
@@ -110,19 +121,16 @@ strings. This needs neither a public API change nor restrictions on declaration
|
|||||||
size or depth. It completes the selected design without promising that all App
|
size or depth. It completes the selected design without promising that all App
|
||||||
construction becomes linear.
|
construction becomes linear.
|
||||||
|
|
||||||
**Verification and status:** a temporary public consumer installed a valid
|
**Audit verification:** a temporary public consumer installed a valid
|
||||||
32-node shared prefix with 64 leaf siblings and dispatched a leaf successfully.
|
32-node shared prefix with 64 leaf siblings and dispatched a leaf successfully.
|
||||||
The prefix depth was selected at an ordinary slice-capacity boundary. This
|
The prefix depth was selected at an ordinary slice-capacity boundary. This
|
||||||
confirms that the workload shape is accepted; it is not a timing or allocation
|
confirms that the workload shape is accepted; it is not a timing or allocation
|
||||||
measurement. The copying bound follows from the recursive slice-header ownership
|
measurement. The copying bound follows from the recursive slice-header ownership
|
||||||
and append semantics above.
|
and append semantics above.
|
||||||
|
|
||||||
Use existing declaration/registry behavioral checks to preserve results, and
|
At audit time, Stage 17 and F22 were marked complete without accounting for this
|
||||||
review that grown capacity survives sibling traversal. Include a branching
|
branching case. Their completion evidence now records the shared slice remedy
|
||||||
shape when checking the remedy; a chain alone misses this case. No timing
|
and links to this follow-up.
|
||||||
threshold or benchmark is necessary. Stage 17 and F22 are currently marked
|
|
||||||
complete; their completion evidence should be corrected to account for this
|
|
||||||
remaining case when remediation is performed.
|
|
||||||
|
|
||||||
## Validation and limits
|
## Validation and limits
|
||||||
|
|
||||||
@@ -133,7 +141,29 @@ cached Go 1.27.0 binary with `GOTOOLCHAIN=local`, `GOPROXY=off`, and
|
|||||||
Cached successful results were reused for unchanged code. Those suites validate
|
Cached successful results were reused for unchanged code. Those suites validate
|
||||||
behavior, not asymptotic copy costs.
|
behavior, not asymptotic copy costs.
|
||||||
|
|
||||||
No production code, repository tests, manifests or existing roadmap records were
|
During the audit, no production code, repository tests, manifests or existing
|
||||||
modified. No benchmarks, performance profiles, real-world latency/memory data,
|
roadmap records were modified. No benchmarks, performance profiles, real-world
|
||||||
external services, credentials or publication operations were used. No additional
|
latency/memory data, external services, credentials or publication operations were
|
||||||
ordinary correctness defect was established during this algorithmic review.
|
used. No additional ordinary correctness defect was established during this
|
||||||
|
algorithmic review.
|
||||||
|
|
||||||
|
## Remediation verification
|
||||||
|
|
||||||
|
The focused declaration/registry checks passed uncached, including retained
|
||||||
|
causes, absence, invalid declarations, nested root-only groups and transactional
|
||||||
|
installation. The independent core suite and aligned three-module suite also
|
||||||
|
passed offline using cached Go 1.27.0 with `GOTOOLCHAIN=local`, `GOPROXY=off` and
|
||||||
|
`-mod=readonly`. The aligned command was
|
||||||
|
`go test -mod=readonly ./... ./integrations/ckconfig/... ./integrations/ckprompt/...`;
|
||||||
|
the independent core check used `GOWORK=off go test -mod=readonly ./...`.
|
||||||
|
|
||||||
|
The temporary public consumer was rerun successfully with a valid depth-32 prefix
|
||||||
|
and 64 leaf siblings. This checks installation and dispatch for the branching
|
||||||
|
shape. Source inspection establishes the complexity improvement: all recursive
|
||||||
|
calls update the same slice header, growth survives return, and each node's
|
||||||
|
deferred truncation restores its parent's path on every exit. Owned diagnostic
|
||||||
|
strings are constructed before sibling traversal can change the scratch path.
|
||||||
|
|
||||||
|
Existing behavioral tests were reused; no timing/allocation threshold or new
|
||||||
|
benchmark was introduced. These results concern this validation walk; other
|
||||||
|
construction phases retain their own costs.
|
||||||
|
|||||||
Reference in New Issue
Block a user